﻿//
//                                                                                 (C) SocketCoder.Com 
// Note: This Project is just some simple samples, if you are looking for a production solution Visit 
// SocketCoder.Com to Buy The Full WCS Web Conferencing Solution Source Code. 
//
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using NSpeex;

    public class SpeexEncoderDecoder
    {
        protected readonly SpeexEncoder _SpeexEncoder = new SpeexEncoder(BandMode.Wide);
        protected readonly SpeexDecoder _SpeexDecoder = new SpeexDecoder(BandMode.Wide);
        
        private int _VoiceQuality = 6;
        
           public int VoiceQuality
            {
                set
                {
                   _VoiceQuality = this._SpeexEncoder.Quality = value;
                }
                get
                {
                    return _VoiceQuality;
                }
            }

        public SpeexEncoderDecoder()
        {
            this._SpeexEncoder.Quality = _VoiceQuality;
        }

        public byte[] Decode(byte[] encodedData, int SamplesPerSecond,int Channels)
        {
            try
            {
                short[] decodedFrame = new short[SamplesPerSecond * Channels];
                int decodedBytes = _SpeexDecoder.Decode(encodedData, 0, encodedData.Length, decodedFrame, 0, false);

                byte[] decodedAudioData = null;

                decodedAudioData = new byte[decodedBytes * 2];

                try
                {
                    for (int shortIndex = 0, byteIndex = 0; shortIndex < decodedBytes; shortIndex++, byteIndex += 2)
                    {
                        byte[] temp = BitConverter.GetBytes(decodedFrame[shortIndex]);
                        decodedAudioData[byteIndex] = temp[0];
                        decodedAudioData[byteIndex + 1] = temp[1];
                    }
                }
                catch 
                {
                   return decodedAudioData;
                }
                return decodedAudioData;
            }
            catch 
            {
                return new byte[0] ;
            }
        }

        public byte[] Encode(byte[] rawData)
        {
            // NSpeex encoder expects as input data contained in variable of short data type array
            // hence we devide the length by 2 because short holds 2 bytes
            var inDataSize = rawData.Length / 2;

            // create array to hold the raw data
            var inData = new short[inDataSize];

            // transfer the raw data 2 bytes at a time
            for (int index = 0; index < rawData.Length; index += 2)
            {
                inData[index / 2] = BitConverter.ToInt16(rawData, index);
            }

            // raw data size should be multiple of the encoder frameSize i.e. 320
            inDataSize = inDataSize - inDataSize % _SpeexEncoder.FrameSize;
            var encodedData = new byte[rawData.Length];
            var encodedBytes = _SpeexEncoder.Encode(inData, 0, inDataSize, encodedData, 0, encodedData.Length);
            byte[] encodedAudioData = null;
            if (encodedBytes != 0)
            {
                // reinitialize the array to the size of the encodedData
                encodedAudioData = new byte[encodedBytes];

                // now copy the encoded bytes to our new array
                Array.Copy(encodedData, 0, encodedAudioData, 0, encodedBytes);
            }

            return encodedAudioData;
        }


    }
    internal static class Converters
    {
        public static byte[] ToByteArray(this short[] array)
        {
            byte[] dst = new byte[array.Length * 2];
            Buffer.BlockCopy(array, 0, dst, 0, dst.Length);
            return dst;
        }

        public static short[] ToShortArray(this byte[] array)
        {
            short[] dst = new short[array.Length / 2];
            Buffer.BlockCopy(array, 0, dst, 0, array.Length);
            return dst;
        }
    }

